using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Data.SqlClient;
namespace Inf {
	static class InfLog {
		public static DAL dataLayer;
		[STAThread]
		static void MainX() {

			DateTime start=DateTime.ParseExact("2013-07-01","yyyy-MM-dd",null);
			DateTime end=DateTime.ParseExact("2013-07-09","yyyy-MM-dd",null);
			dataLayer=new DAL("WebVisitLog");
			string[] folders={ @"\\pon-wpwb01-cl01\c$\WINDOWS\system32\LogFiles\W3SVC1\",@"\\pon-wpwb01-cl02\c$\WINDOWS\system32\LogFiles\W3SVC1\" };
			Master visits=new Master("Visit");
			Distinct durl=new Distinct("Url",100);
			Distinct dlogin=new Distinct("Login",20);
			Distinct dip=new Distinct("IP",20);
			Distinct dqstr=new Distinct("QStr",200);
			Distinct dClust=new Distinct("Clust",100);
			string todayPart=DateTime.Now.ToString("yyMMdd");
			foreach(string folder in folders)
				foreach(string file in Directory.GetFiles(folder))
					if(!file.Contains(todayPart))
					{
						string datePart=file.Substring(file.Length-10,6);
						DateTime fileDate=DateTime.ParseExact(datePart,"yyMMdd",null);
						if(fileDate>=start&&fileDate<=end)
						{
							Console.WriteLine(file);
							string[] lines;
							using(PM.Run("GetData"))
								lines=File.ReadAllLines(file);
							Console.WriteLine("Rows:"+lines.Length);
							int notValidEntry=0;
							int validEntry=0;
							using(PM.Run("Process"))
							{
								string detector="next-plc\\";
								foreach(string str in lines)
									if(str.ToLower().Contains(detector))
									{
										string[] entries=str.Split(' ');
										string date=fileDate.ToString("yyyy-MM-dd");
										string time=entries[0];
										string login=entries[5].ToLower().Replace(detector,"");
										string ip=entries[6];
										string url=entries[2];
										string queryStr=entries[3];
										int urlId=durl.Add(url);
										int loginId=dlogin.Add(login);
										int ipId=dip.Add(ip);
										int qstrId=dqstr.Add(queryStr);
										int clusterId=dClust.Add(folder);
										DateTime visitTime=DateTime.ParseExact(date+" "+time,"yyyy-MM-dd HH:mm:ss",null);
										visits.SaveToDb(urlId,loginId,ipId,qstrId,clusterId,visitTime);
										validEntry++;
									}
									else
										notValidEntry++;
							}
							Console.WriteLine("Valid/Inv:{0}/{1}",validEntry,notValidEntry);
						}
					}
		}
	}
	class Master {
		string tableName;
		public Master(string TableName) {
			tableName=TableName;
			string create=@"if exists(SELECT * FROM sysobjects WHERE name='{0}')drop table {0} create table {0}(urlId int,loginId int,ipId int,qstrId int,clustId int,visitTime datetime)";
			InfLog.dataLayer.RunSQL(create,tableName);
		}
		internal void SaveToDb(int urlId,int loginId,int ipId,int qstrId,int clusterId,DateTime visitTime) {
			string insert="insert into {0}(urlId,loginId,ipId,qstrId,clustId,visitTime)values({1},{2},{3},{4},{5},convert(datetime,'{6}',120))";
			InfLog.dataLayer.RunSQL(insert,tableName,urlId,loginId,ipId,qstrId,clusterId,visitTime.ToString("yyyy-MM-dd hh:mm:ss"));
		}
	}
	class Distinct {
		int maxLen;
		string tableName;
		int id=1;
		public Distinct(string TableName,int MaxLen) {
			tableName=TableName;
			maxLen=MaxLen;
			string create=@"if exists(SELECT * FROM sysobjects WHERE name='{0}')drop table {0} create table {0}(id int,val varchar({1}))";
			InfLog.dataLayer.RunSQL(create,tableName,maxLen);
		}
		Dictionary<string,int> lst=new Dictionary<string,int>();
		string insert="insert into {0}(id,val)values({1},'{2}')";
		public int Add(string key) {
			key=key.Replace("'","''");
			if(key.Length>maxLen)
				key=key.Substring(0,maxLen);
			if(!lst.ContainsKey(key))
			{
				lst.Add(key,id);
				InfLog.dataLayer.RunSQL(insert,tableName,id,key);
				id++;
			}
			return lst[key];
		}
		public override string ToString() { return lst.Count.ToString(); }
	}
	public class PM:IDisposable {
		public static PM Run(object target) {
			return new PM(target);
		}
		//public static TimeSpan LE;
		private Stopwatch sw;
		private string target;
		private PM(object target) {
			this.sw=Stopwatch.StartNew();
			this.target=target.ToString();
		}
		public void Dispose() {
			sw.Stop();
			Console.WriteLine(target.ToString().PadRight(100,'.')+sw.Elapsed);
		}
	}
	class DAL {
		string _dbName;
		public DAL(string dbName) {

			RunSQL("create database [{0}]",dbName);
			_dbName=dbName;
		}

		static string conStr="server=localhost;database={0};integrated security=sspi";
		public int RunSQL(string sqlForm,params object[] values) {
			string sql=string.Format(sqlForm,values);
			int ret=0;
			using(SqlConnection con=new SqlConnection(string.Format(conStr,_dbName)))
			using(SqlCommand cmd=new SqlCommand(sql,con))
			{
				con.Open();
				ret=cmd.ExecuteNonQuery();
			}
			return ret;
		}
	}
}